package com.lemon.components.ant;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lemon.components.ant.beans.EnumInfo;
import com.lemon.components.ant.beans.EnumInfo.EnumAttr;
import com.lemon.components.ant.beans.FormData;
import com.lemon.components.ant.beans.Grid;
import com.lemon.components.ant.beans.SelectItem;
import com.lemon.components.ant.beans.TableColumns;
import com.lemon.components.ant.util.ClassUtil;
import com.lemon.components.ant.util.CodeMakerPropertiesUtil;
import com.lemon.components.common.result.ResultBase;

@Controller
@RequestMapping("codemaker")
public class CodeMakerController {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	/**
	 * 
	 * <font size="3" color="red">跳转到配置页面</font><br>
	 * <ol>
	 * <li></li>
	 * </ol>
	 * @return <font size="2" color="blue"></font>
	 */
	@RequestMapping("index.htm")
	public String topage(){
		return "/system/codemaker/codemaker-config";
	}

	/**
	 * 
	 * <font size="3" color="red">载入基础配置文件</font><br>
	 * <ol>
	 * <li></li>
	 * </ol>
	 * @return <font size="2" color="blue"></font>
	 */
	@ResponseBody
	@RequestMapping("loadConfig.json")
	public FormData configLoad(){
		FormData formData = new FormData();
		
		JSONObject context = new JSONObject();
		context.put("html.path", CodeMakerPropertiesUtil.get("html.path"));
		context.put("js.path", CodeMakerPropertiesUtil.get("js.path"));
		context.put("js.prefix", CodeMakerPropertiesUtil.get("js.prefix"));
		context.put("service.path", CodeMakerPropertiesUtil.get("service.path"));
		context.put("controller.path", CodeMakerPropertiesUtil.get("controller.path"));
		context.put("controller.prefix", CodeMakerPropertiesUtil.get("controller.prefix"));
		context.put("serviceName", CodeMakerPropertiesUtil.get("serviceName"));
		context.put("modelName", CodeMakerPropertiesUtil.get("modelName"));
		context.put("primaryKey", CodeMakerPropertiesUtil.get("primaryKey"));
		
		formData.setData(context);
		formData.setSuccess(true);
		return formData;
	}
	
	/**
	 * 
	 * <font size="3" color="red">更新基础配置文件</font><br>
	 * <ol>
	 * <li></li>
	 * </ol>
	 * @param request
	 * @return <font size="2" color="blue"></font>
	 */
	@ResponseBody
	@RequestMapping("updateConfig.json")
	public FormData configUpdate(HttpServletRequest request){
		FormData result = new FormData();
		result.setSuccess(true);
		
		for(String key:request.getParameterMap().keySet()){
			CodeMakerPropertiesUtil.set(key, request.getParameter(key));
		}
		result.setMsg("更新成功");
		return result;
	}
	
	@ResponseBody
	@RequestMapping("modelSelect.json")
	public JSONArray modelNameSelect(){
		JSONArray list = new JSONArray();
		File file = new File("./src/main/java");
		for(String tmp:ClassUtil.getPackageAllClassName(file.getAbsolutePath(), "com.lemon.data.model")){
			JSONObject o = new JSONObject();
			String str = tmp.split("\\.")[0];
			o.put("name", str);
			if(!str.endsWith("Example"))
				list.add(o);
		}
		
		return list;
	}
	
	@ResponseBody
	@RequestMapping("modelPropertiesSelect.json")
	public JSONArray modelPropertiesSelect(String clazz){
		if(StringUtils.isBlank(clazz)){
			return null;
		}
		JSONArray list = new JSONArray();
		PropertyDescriptor[] pds = ClassUtil.getClassDescriptor("com.lemon.data.model."+clazz);
		for(PropertyDescriptor pd:pds){
			JSONObject o = new JSONObject();
			o.put("name", pd.getName());
			list.add(o);
		}
		return list;
	}
	
	@ResponseBody
	@RequestMapping("columns.json")
	public Grid<TableColumns> getColumns(){
		Grid<TableColumns> grid = new Grid<TableColumns>();
		grid.setSuccess(true);
		grid.setData(JSONArray.parseArray(CodeMakerPropertiesUtil.get("columns"), TableColumns.class));
		return grid;
	}
	
	@ResponseBody
	@RequestMapping("getColumnByName.json")
	public FormData getColumnByName(String code){
		FormData formData = new FormData();
		List<TableColumns> list = JSONArray.parseArray(CodeMakerPropertiesUtil.get("columns"), TableColumns.class);
		TableColumns tc = list.stream().filter(item -> item.getCode().equalsIgnoreCase(code)).findFirst().orElse(null);
		formData.setData(tc);
		formData.setSuccess(true);
		return formData;
	}
	
	@ResponseBody
	@RequestMapping("getEnumItemByName.json")
	public FormData getEnumItemByName(String name,String enumName){
		FormData formData = new FormData();
		JSONObject tc = new JSONObject();
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
		for(EnumInfo enumInfo:enumlist){
			if(enumInfo.getName().equalsIgnoreCase(name)){
				for(EnumAttr attr:enumInfo.getAttr()){
					if(enumName.equalsIgnoreCase(attr.getEnumName())){
						tc.put("name", enumInfo.getName());
						tc.put("enumName", attr.getEnumName());
						tc.put("code", attr.getCode());
						tc.put("msg", attr.getMsg());
						break;
					}
				}
			}
		}
		formData.setData(tc);
		formData.setSuccess(true);
		return formData;
	}
	
	/**
	 * 
	 * <font size="3" color="red">获取枚举类</font><br>
	 * <ol>
	 * <li>和getEnums的区别是，getEnums可以获取枚举值，而本方法只获取枚举类</li>
	 * </ol>
	 * @return <font size="2" color="blue"></font>
	 */
	@ResponseBody
	@RequestMapping("enumItem.json")
	public List<EnumInfo> getEnumItems(){
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
		return enumlist;
	}
	
	/**
	 * 
	 * <font size="3" color="red">获取枚举值</font><br>
	 * <ol>
	 * <li>每个枚举值都携带枚举类名</li>
	 * </ol>
	 * @return <font size="2" color="blue"></font>
	 */
	@ResponseBody
	@RequestMapping("enums.json")
	public Grid<JSONObject> getEnums(){
		Grid<JSONObject> grid = new Grid<JSONObject>();
		
		List<JSONObject> data = new ArrayList<>();
		
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
			enumlist.forEach(enumInfo -> {
				if(enumInfo.getAttr() != null && enumInfo.getAttr().size() > 0){
					enumInfo.getAttr().forEach(enumAttr ->{
						JSONObject jsonInfo = new JSONObject();
						jsonInfo.put("name", enumInfo.getName());
						jsonInfo.put("code", enumAttr.getCode());
						jsonInfo.put("msg", enumAttr.getMsg());
						jsonInfo.put("enumName", enumAttr.getEnumName());
						data.add(jsonInfo);
					});
				}
			});
		
		grid.setSuccess(true);
		grid.setData(data);
		return grid;
	}
	
	
	@ResponseBody
	@RequestMapping("addGridColumn.json")
	public FormData gridColumnAdd(TableColumns tableColumns,HttpServletRequest request){
		FormData result = new FormData();
		String columnsStr = CodeMakerPropertiesUtil.get("columns");
		List<TableColumns> list = JSONArray.parseArray(columnsStr, TableColumns.class);
		if(StringUtils.isNotBlank(request.getParameter("selectStr"))){
			SelectItem selectItem = new SelectItem();
			selectItem.setType("enum");
			selectItem.setClazz(request.getParameter("selectStr"));
			tableColumns.setSelect(selectItem);
		}
		if(request.getParameter("searchStr").equalsIgnoreCase("yes")){
			tableColumns.setSearch(true);
		}
		list.add(tableColumns);
		CodeMakerPropertiesUtil.set("columns", JSONArray.toJSONString(list,SerializerFeature.WriteNullListAsEmpty));
		result.setMsg("更新成功");
		result.setSuccess(true);
		return result;
	}
	
	@ResponseBody
	@RequestMapping("updateGridColumn.json")
	public FormData gridColumnUpdate(TableColumns tableColumns,HttpServletRequest request){
		FormData result = new FormData();
		String columnsStr = CodeMakerPropertiesUtil.get("columns");
		List<TableColumns> list = JSONArray.parseArray(columnsStr, TableColumns.class);
		for(TableColumns tctmp:list){
			if(tctmp.getCode().equalsIgnoreCase(tableColumns.getCode())){
				try {
					BeanUtils.copyProperties(tctmp, tableColumns);
					if(StringUtils.isNotBlank(tableColumns.getSearchStr())&&tableColumns.getSearchStr().equalsIgnoreCase("yes")){
						tctmp.setSearch(true);
					} else {
						tctmp.setSearch(false);
					}
					/**
					 * select 处理
					 */
					if(StringUtils.isNotBlank(request.getParameter("selectStr"))){
						if(tctmp.getSelect() != null){
							tctmp.getSelect().setClazz(request.getParameter("selectStr"));
						} else {
							SelectItem selectItem = new SelectItem();
							selectItem.setClazz(request.getParameter("selectStr"));
							selectItem.setType("enum");
							tctmp.setSelect(selectItem);
						}
					} else {
						tctmp.setSelect(null);
					}
					/**
					 * search 处理
					 */
					if(StringUtils.isNotBlank(request.getParameter("searchStr"))&&request.getParameter("searchStr").equalsIgnoreCase("yes")){
						tctmp.setSearch(true);
					} else {
						tctmp.setSearch(false);
					}
				} catch (Exception e) {
					e.printStackTrace();
					result.setSuccess(false);
					result.setErrorMessage(e.getMessage());
					return result;
				}
			}
		}
		String tmpjson = JSONArray.toJSONString(list,SerializerFeature.WriteNullListAsEmpty);
		CodeMakerPropertiesUtil.set("columns", tmpjson);
		result.setMsg("更新成功");
		result.setSuccess(true);
		return result;
	}
	
	@ResponseBody
	@RequestMapping("deleteGridColumn.json")
	public ResultBase gridColumnDelete(TableColumns tableColumns){
		ResultBase result = new ResultBase();
		if(StringUtils.isBlank(tableColumns.getCode())){
			result.setSuccess(false);
			result.setMessage("删除参数code为空，删除失败");
			return result;
		}
		String columnsStr = CodeMakerPropertiesUtil.get("columns");
		List<TableColumns> list = JSONArray.parseArray(columnsStr, TableColumns.class);
		List<TableColumns> tobeDelete = new ArrayList<>();
		String[] tmp = tableColumns.getCode().split(",");
		
		for(TableColumns tctmp:list){
			if(ArrayUtils.contains(tmp, tctmp.getCode())){
				tobeDelete.add(tctmp);
			}
		}
		if( tobeDelete.size() > 0 ){
			list.removeAll(tobeDelete);
			CodeMakerPropertiesUtil.set("columns", JSONArray.toJSONString(list,SerializerFeature.WriteNullListAsEmpty));
			result.setSuccess(true);
		} else {
			result.setSuccess(false);
			result.setMessage("未找到被删除项");
		}
		return result;
	}
	
	@ResponseBody
	@RequestMapping("enumAdd.json")
	public FormData enumAdd(@Valid EnumInfo enumInfo,@Valid EnumAttr enumAttr){
		FormData formData = new FormData();
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
		boolean find = false;
		for(EnumInfo tmp:enumlist){
			if(enumInfo.getName().equalsIgnoreCase(tmp.getName())){
				find = true;
				tmp.getAttr().add(enumAttr);
			}
		}
		if(!find){
			List<EnumAttr> list = new ArrayList<>();
			list.add(enumAttr);
			enumInfo.setAttr(list);
			enumlist.add(enumInfo);
		}
		String tmpjson = JSONArray.toJSONString(enumlist,SerializerFeature.WriteNullListAsEmpty);
		CodeMakerPropertiesUtil.set("enums", tmpjson);
		formData.setSuccess(true);
		return formData;
	}
	
	@ResponseBody
	@RequestMapping("enumUpdate.json")
	public FormData enumUpdate(@Valid EnumInfo enumInfo,@Valid EnumAttr enumAttr){
		FormData formData = new FormData();
		logger.debug(enumInfo.toString());
		logger.debug(enumAttr.toString());
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
		for(EnumInfo info:enumlist){
			if(info.getName().equalsIgnoreCase(enumInfo.getName())){
				for(EnumAttr attr:info.getAttr()){
					if(enumAttr.getEnumName().equalsIgnoreCase(attr.getEnumName())){
						attr.setMsg(enumAttr.getMsg());
						attr.setCode(enumAttr.getCode());
					}
				}
			}
		}
		String tmpjson = JSONArray.toJSONString(enumlist,SerializerFeature.WriteNullListAsEmpty);
		CodeMakerPropertiesUtil.set("enums", tmpjson);
		formData.setMsg("成功了");
		formData.setSuccess(true);
		return formData;
	}
	
	@ResponseBody
	@RequestMapping("enumDelete.json")
	public ResultBase enumDelete(EnumAttr enumAttr){
		ResultBase resultBase = new ResultBase();
		if(StringUtils.isBlank(enumAttr.getCode())){
			resultBase.setMessage("code为空，删除失败。");
			return resultBase;
		}
		List<EnumInfo> enumlist = JSONArray.parseArray(CodeMakerPropertiesUtil.get("enums"), EnumInfo.class);
		List<EnumAttr> attrTobeDelete = new ArrayList<EnumAttr>();
		for(EnumInfo enumInfo:enumlist){
			for(String tmp:enumAttr.getCode().split(",")){
				String[] item = tmp.split("\\|");
				if(enumInfo.getName().equalsIgnoreCase(item[0])){
					for(EnumAttr attr:enumInfo.getAttr()){
						if(attr.getCode().equalsIgnoreCase(item[1])){
							attrTobeDelete.add(attr);
						}
					}
				}
			}
		}
		List<EnumInfo> removedEnumInfo = new ArrayList<>();
		for(EnumInfo info:enumlist){
			info.getAttr().removeAll(attrTobeDelete);
			if(info.getAttr().size() == 0){
				removedEnumInfo.add(info);
			}
		}
		if(removedEnumInfo.size() > 0){
			enumlist.removeAll(removedEnumInfo);
		}
		if( attrTobeDelete.size() > 0 ){
			CodeMakerPropertiesUtil.set("enums", JSONArray.toJSONString(enumlist,SerializerFeature.WriteNullListAsEmpty));
			resultBase.setSuccess(true);
		} else {
			resultBase.setSuccess(false);
			resultBase.setMessage("未找到被删除项");
		}
		return resultBase;
	}
}
